from multiprocessing.managers import BaseManager
from multiprocessing import Queue,Process,RawArray,RLock
import time,signal,os,sys,json
 
class QueueManager(BaseManager): pass
fpid = os.getpid()

def kill_handler(signum,frame):
    print('exit manager process')
    sys.exit(0)

def send_msg(pid,msg,ms):
    ms.put(msg)
    os.kill(pid,signal.SIGUSR1)

def msg_server( ):
    import time
    time.sleep(1)
    QueueManager.register('q_server')
    QueueManager.register('q_client')
    m = QueueManager(address=('localhost', 50000), authkey='abracadabra'.encode('utf-8'))
    m.connect()
    qs = m.q_server()
    qc = m.q_client()
    client_list = []
    print('loop start')
    n=0
    while True:
        if n>15:
            break
        try:
            msg = qs.get()
            print( msg )
            if msg['type'] is 'r':
                print('user register')
                n += 1
                for u1 in client_list:
                    if u1[1]==msg['value']:
                        client_list.remove(u1)
                user1 = ( msg['from'], msg['value'] )
                client_list.append( user1 )
                msg =  {'from':'@', 'value':'hello'}
                send_msg(user1[1],msg,qc)
                print(n)
            elif msg['type'] is 'p':
                for u1 in client_list:
                    send_msg(u1[1], msg, qc)
            elif msg['type'] is 'm':
                flag = False
                from_pid = None
                for u1 in client_list:
                    if u1[0]==msg['to']:
                        send_msg(u1[1], msg, qc)
                        flag = True
                    if u1[0]==msg['from']:
                        from_pid = u1[1]
                if not flag:
                    send_msg(from_pid, {'from':'', 'value':'notExist'}, qc)
        except Exception as e:
            print('class:'+str(e.__class__))
            print('string:'+str(e))
            pass
    print('msg_server exit\n')
    for u1 in client_list:
        print(u1)

#class mem_share:
    #mem = RawArray('u',1024)
    #locker = RLock()
    #def put( self,s ):
        #self.locker.acquire()
        #self.mem.value = json.dumps(s)
        #self.locker.release()
    #def get(self):
        #self.locker.acquire()
        #res = json.loads(self.mem.value)
        #self.locker.release()
        #return res


def run_manager():
    #run in child process
    q_server = Queue()
    q_client = Queue()

    QueueManager.register('q_server', callable=lambda:q_server)
    QueueManager.register('q_client', callable=lambda:q_client)
    m = QueueManager(address=('', 50000), authkey='abracadabra'.encode('utf-8'))
    s = m.get_server()
    print('manager start')
    signal.signal(signal.SIGTERM,kill_handler)
    s.serve_forever()
    
p = Process(target=run_manager, args=())
p.start()

#run in main process
msg_server( )
p.terminate()
